<script setup lang="ts">
import {computed, ref, watch} from 'vue'
import type PaginationProp from "@/components/pagination/PaginationProp.ts";

const emit = defineEmits(['change', 'showSizeChange'])
const props = withDefaults(
    defineProps<PaginationProp>(),
    {
      pageNo: 1,
      pageSize: 10,
      showSize: 5,
      showTotal: true,
      showJumper: true,
      showSizeChanger: true,
      pageSizeOptions: () => [10, 20, 50, 100]
    }
)

// 响应式数据
const currentPage = ref(props.pageNo)
const currentPageSize = ref(props.pageSize)
const jumpPage = ref('')

// 计算属性
const totalPages = computed(() => {
  return Math.ceil(props.total / currentPageSize.value)
})

// 可见页码数组
const visiblePages = computed(() => {
  const pages = []
  const half = Math.floor(props.showSize / 2)
  let start = Math.max(2, currentPage.value - half)
  let end = Math.min(totalPages.value - 1, currentPage.value + half)

  // 调整范围以保持显示的页码数量
  if (end - start + 1 < props.showSize - 2) {
    if (start === 2) {
      end = Math.min(totalPages.value - 1, start + props.showSize - 3)
    } else if (end === totalPages.value - 1) {
      start = Math.max(2, end - props.showSize + 3)
    }
  }

  for (let i = start; i <= end; i++) {
    pages.push(i)
  }

  return pages
})

// 是否显示首页
const showFirstPage = computed(() => {
  return (totalPages.value > 1 && (!visiblePages.value.length || visiblePages.value[0] > 2)) || (totalPages.value === 1)
})

// 是否显示末页
const showLastPage = computed(() => {
  return totalPages.value > 1 && (!visiblePages.value.length || visiblePages.value[visiblePages.value.length - 1] < totalPages.value - 1)
})

// 是否显示左省略号
const showLeftEllipsis = computed(() => {
  return visiblePages.value.length && visiblePages.value[0] > 2
})

// 是否显示右省略号
const showRightEllipsis = computed(() => {
  return visiblePages.value.length && visiblePages.value[visiblePages.value.length - 1] < totalPages.value - 1
})

// 方法
const handlePageClick = (page: number) => {
  if (page !== currentPage.value) {
    currentPage.value = page
    emit('change', page, currentPageSize.value)
  }
}

const handlePrevious = () => {
  if (currentPage.value > 1) {
    handlePageClick(currentPage.value - 1)
  }
}

const handleNext = () => {
  if (currentPage.value < totalPages.value) {
    handlePageClick(currentPage.value + 1)
  }
}

const handleJump = () => {
  const page = parseInt(jumpPage.value)
  if (page >= 1 && page <= totalPages.value && page !== currentPage.value) {
    handlePageClick(page)
  }
  jumpPage.value = ''
}

const handleSizeChange = () => {
  // 计算新的页码位置
  const newPage = Math.ceil((currentPage.value - 1) * props.pageSize / currentPageSize.value) + 1
  currentPage.value = Math.min(newPage, Math.ceil(props.total / currentPageSize.value))

  emit('showSizeChange', currentPage.value, currentPageSize.value)
  emit('change', currentPage.value, currentPageSize.value)
}

// 监听props变化
watch(() => props.current, (newVal) => {
  currentPage.value = newVal
})

watch(() => props.pageSize, (newVal) => {
  currentPageSize.value = newVal
})
</script>

<template>
  <div class="pagination-wrapper">
    <!-- 总条数显示 -->
    <div class="pagination-info" v-if="showTotal">
      共 {{ total }} 条数据，{{ totalPages }}页
    </div>

    <div class="pagination-container">
      <!-- 上一页 -->
      <button
          class="pagination-btn"
          :class="{ disabled: currentPage === 1 }"
          :disabled="currentPage === 1"
          @click="handlePrevious"
      >
        Prev
      </button>

      <!-- 页码按钮 -->
      <div class="pagination-pages">
        <!-- 首页 -->
        <button
            v-if="showFirstPage"
            class="pagination-page"
            :class="{ active: currentPage === 1 }"
            @click="handlePageClick(1)"
        >
          1
        </button>

        <!-- 左省略号 -->
        <span v-if="showLeftEllipsis" class="pagination-ellipsis">...</span>

        <!-- 中间页码 -->
        <button
            v-for="page in visiblePages"
            :key="page"
            class="pagination-page"
            :class="{ active: currentPage === page }"
            @click="handlePageClick(page)"
        >
          {{ page }}
        </button>

        <!-- 右省略号 -->
        <span v-if="showRightEllipsis" class="pagination-ellipsis">...</span>

        <!-- 末页 -->
        <button
            v-if="showLastPage"
            class="pagination-page"
            :class="{ active: currentPage === totalPages }"
            @click="handlePageClick(totalPages)"
        >
          {{ totalPages }}
        </button>
      </div>

      <!-- 下一页 -->
      <button
          class="pagination-btn"
          :class="{ disabled: currentPage === totalPages }"
          :disabled="currentPage === totalPages"
          @click="handleNext"
      >
        Next
      </button>
    </div>

    <!-- 快速跳转 -->
    <div class="pagination-jumper" v-if="showJumper">
      跳转至
      <input
          type="number"
          :min="1"
          :max="totalPages"
          v-model.number="jumpPage"
          @keyup.enter="handleJump"
          class="jump-input"
      >
      页
      <button @click="handleJump" class="jump-btn">go</button>
    </div>

    <!-- 页面大小选择器 -->
    <div class="pagination-size-selector" v-if="showSizeChanger">
      <select v-model="currentPageSize" @change="handleSizeChange" class="size-select">
        <option v-for="size in pageSizeOptions" :key="`size-${size}`" :value="size">
          {{ size }} 条/页
        </option>
      </select>
    </div>
  </div>
</template>

<style scoped>
.pagination-wrapper {
  width: 100%;
  display: flex;
  justify-content: right;
  margin: 5px 0;
  align-items: center;
  gap: 16px;
  font-size: 14px;
  flex-wrap: wrap;
}

.pagination-info {
  color: #666;
}

.pagination-container {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pagination-btn {
  padding: 1px 12px;
  border: 1px solid #d9d9d9;
  background: #fff;
  color: #333;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s;
}

.pagination-btn:hover:not(.disabled) {
  border-color: #1890ff;
  color: #1890ff;
}

.pagination-btn.disabled {
  color: #ccc;
  cursor: not-allowed;
  background: #f5f5f5;
}

.pagination-pages {
  display: flex;
  align-items: center;
  gap: 4px;
}

.pagination-page {
  padding: 2px 10px;
  border: none;
  background: #fff;
  color: #333;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pagination-page:hover {
  border-color: #1890ff;
  color: #1890ff;
}

.pagination-page.active {
  background: #1890ff;
  border-color: #1890ff;
  color: #fff;
}

.pagination-ellipsis {
  color: #999;
  padding: 0 4px;
}

.pagination-jumper {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #666;
}

.jump-input {
  width: 50px;
  padding: 1px 0;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  text-align: center;
}

.jump-btn {
  padding: 1px 8px;
  border: 1px solid #d9d9d9;
  background: #fff;
  color: #333;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s;
}

.jump-btn:hover {
  border-color: #1890ff;
  color: #1890ff;
}

.pagination-size-selector {
  color: #666;
}

.size-select {
  padding: 1px 8px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
}

.size-select:focus {
  border-color: #1890ff;
  outline: none;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .pagination-wrapper {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .pagination-container {
    flex-wrap: wrap;
  }

  .pagination-pages {
    flex-wrap: wrap;
  }
}</style>